﻿/*
Copyright (C) 21/05/2010  Matthew "Scent Tree" Perry
scent.tree@gmail.com

This library/program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This libary/program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
using System;
using BaseTools.Strings;
using BaseTools.Searching;
using BaseTools.Configuration;


namespace DoomTools
{
	/// <summary>
	/// Description of DecorateParser.
	/// </summary>
	public class DecorateParser
	{
		public static ParseInfo DecorateParseInfo()
		{
			return new ParseInfo(
				new ParseSequence[] {
					new ParseSequence("//", ParseType.LineComment),
					new ParseSequence("/*", ParseType.OpenComment),
					new ParseSequence("*/", ParseType.CloseComment)
				}, new ParseChar[] {
					new ParseChar('"', ParseType.ToggleQuote),
					new ParseChar('\\', ParseType.BeginEscape),
					new ParseChar('{', ParseType.Special),
					new ParseChar('}', ParseType.Special),
					new ParseChar('+', ParseType.Special),
					new ParseChar(':', ParseType.Special),
					new ParseChar(',', ParseType.Special),
					new ParseChar('\r', ParseType.Newline | ParseType.Whitespace),
					new ParseChar('\n', ParseType.Newline | ParseType.Whitespace),
					new ParseChar(' ', ParseType.Whitespace),
					new ParseChar('\t', ParseType.Whitespace)
				}, new EscapeSequence[] {
					new EscapeSequence('r', '\r'),
					new EscapeSequence('n', '\n'),
					new EscapeSequence('t', '\t'),
					new EscapeSequence('\\', '\\'),
					new EscapeSequence('"', '"')
				}, true
			);
		}
		public static bool IsNumericInt(string s)
		{
			int k = default(int);
			
			return int.TryParse(s, out k);
		}
		public static bool IsNumericDouble(string s)
		{
			double k = default(double);
			
			return double.TryParse(s, out k);
		}
		
		public DecorateParser()
		{
		}
		
		
		public RawDecorate ParseDecorate(ICharStream str)
		{
			StringParser adpi = new StringParser(DecorateParseInfo(), str);
			RawDecorate parsed = new RawDecorate();
			
			int stage = 0;
			bool hasParent = false;
			
			while(adpi.Available())
			{
				StringBlock token = adpi.ReadBlock();
				
				if (token.IsEmpty)
					continue;
				
				if (stage == 0)
				{
					if (token.Quoted)
						throw new DecorateSyntaxException("Misplaced quote", str);
					else if (token.Match("actor"))
					{
						stage = 1;
					}
				}
				else if (stage == 1)
				{
					if (hasParent)
					{
						hasParent = false;
						parsed.Parent = token;
					}
					else if (token.Match(":"))
					{
						if (parsed.Name == null)
							throw new DecorateSyntaxException("Attempt to inherit without a class name", str);
						hasParent = true;
					}
					else if (token.Match("{"))
					{
						if (parsed.Name == null)
							throw new DecorateSyntaxException("Attempt to define an actor without a class name", str);
						
						stage = 2;
					}
					else if (IsNumericInt(token))
					{
						if (parsed.Name == null)
							throw new DecorateSyntaxException("Attempt to define a DoomEdNum without a class name", str);
						
						parsed.DoomEdNum = int.Parse(token);
					}
					else
					{
						if (parsed.Name == null)
						{
							parsed.Name = token;
						}
						else
						{
							parsed.Replaces = token;
						}
					}
					
				}
				else if (stage == 2)
				{
					if (token.Match("{"))
					{
						stage = 3;
					}
				}
			}
			
			return parsed;
		}
	}
}
